/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.ec.tmall.service.TmallServiceImpl
   Module Description   :

   Date Created      : 2011/10/4
   Original Author   : feeling.wang
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.ec.tmall.service.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Stack;

import javax.annotation.Resource;

import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;

import com.taobao.api.ApiException;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.TaobaoRequest;
import com.taobao.api.TaobaoResponse;
import com.taobao.api.domain.Item;
import com.taobao.api.domain.Order;
import com.taobao.api.domain.PromotionDetail;
import com.taobao.api.domain.PropValue;
import com.taobao.api.domain.Trade;
import com.taobao.api.request.ItemGetRequest;
import com.taobao.api.request.ItempropvaluesGetRequest;
import com.taobao.api.request.TradeFullinfoGetRequest;
import com.taobao.api.request.TradeMemoAddRequest;
import com.taobao.api.request.TradesSoldGetRequest;
import com.taobao.api.request.TradesSoldIncrementGetRequest;
import com.taobao.api.response.ItemGetResponse;
import com.taobao.api.response.ItempropvaluesGetResponse;
import com.taobao.api.response.TradeFullinfoGetResponse;
import com.taobao.api.response.TradesSoldGetResponse;
import com.taobao.api.response.TradesSoldIncrementGetResponse;
import com.yaodian100.core.admin.entity.User;
import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.common.service.BaseManager;
import com.yaodian100.core.common.utils.DateUtil;
import com.yaodian100.core.common.utils.JspUtil;
import com.yaodian100.core.common.utils.StringUtils;
import com.yaodian100.core.logger.service.LogService;
import com.yaodian100.core.menu.entity.Option;
import com.yaodian100.core.menu.service.MenuService;
import com.yaodian100.core.sms.service.SmsService;
import com.yaodian100.crm.cs.service.CsService;
import com.yaodian100.ec.common.EcConstant;
import com.yaodian100.ec.member.entity.Member;
import com.yaodian100.ec.member.service.MemberService;
import com.yaodian100.ec.order.entity.OrderProduct;
import com.yaodian100.ec.order.entity.OrderProductDetail;
import com.yaodian100.ec.order.entity.Orders;
import com.yaodian100.ec.order.service.InterceptOrderService;
import com.yaodian100.ec.order.service.OrderService;
import com.yaodian100.ec.product.entity.Product;
import com.yaodian100.ec.product.entity.Specification;
import com.yaodian100.ec.product.entity.SpecificationInventory;
import com.yaodian100.ec.product.service.Product2Service;
import com.yaodian100.ec.shelf.entity.Shelf;
import com.yaodian100.ec.supplierapply.entity.SupplierApply;
import com.yaodian100.ec.supplierapply.service.SupplierApplyService;
import com.yaodian100.ec.tmall.entity.AddrMapping;
import com.yaodian100.ec.tmall.service.TmallService;

/**
 * @author feeling.wang
 * 
 */
public class TmallServiceImpl implements TmallService {
	private final Logger logger = LoggerFactory.getLogger(TmallServiceImpl.class);

	private String[] apiKey = { "12380686" };
	private String[] apiSecret = { "2c7fbe00393381826a2973487bce9b8d" };
	private final String apiUrl = "http://gw.api.taobao.com/router/rest";

	@Autowired
	private MemberService memberService;
	@Autowired
	private OrderService orderService;
	@Autowired
	private MenuService menuService;
	@Autowired
	private Product2Service productService;
	@Autowired
	private SupplierApplyService supplierApplyService;
	@Autowired
	private LogService logService;
	@Resource
	private BaseManager baseMgr;
	@Resource
	private JdbcTemplate jdbcTemplate;
	@Autowired
	private CsService csService;
	@Autowired
	private SmsService smsService;
	@Autowired(required = false)
	private InterceptOrderService interceptOrderService;

	private boolean isNeedRefund(Trade trade) {
		if ((trade != null) && (trade.getOrders() != null)) {
			for (Order to : trade.getOrders()) {
				if (!to.getRefundStatus().equals("NO_REFUND")) {
					return true;
				}
			}
		}
		return false;
	}

	@Override
	@Transactional(readOnly = false)
	public void updateOrderProductAndDetail(String[] specIds, String[] specNames, OrderProduct op, long opCount,
			OrderProductDetail od, long odCount, String[] productIds) {
		// 若specId数至少为商品总数-1
		if (specIds.length > op.getQty() - 1) {
			BigDecimal[] totalPrices = new BigDecimal[op.getQty()];
			BigDecimal[] discounts = new BigDecimal[op.getQty()];
			BigDecimal[] detailAmounts = new BigDecimal[od.getQty()];
			int prodSeq = (int) opCount;
			int detailSeq = (int) odCount;
			for (int i = 0; i < op.getQty(); i++) {
				totalPrices[i] = op.getTotalPrice().divide(BigDecimal.valueOf(op.getQty())).setScale(2, BigDecimal.ROUND_DOWN);
				discounts[i] = op.getDiscount().divide(BigDecimal.valueOf(op.getQty())).setScale(2, BigDecimal.ROUND_DOWN);
				detailAmounts[i] = od.getAmount().divide(BigDecimal.valueOf(od.getQty())).setScale(2, BigDecimal.ROUND_DOWN);

				if (i == op.getQty() - 1) {
					for (int j = 0; j < totalPrices.length - 1; j++) {
						totalPrices[i] = op.getAmount().subtract(totalPrices[j]);
						discounts[i] = op.getDiscount().subtract(discounts[j]);
					}

					op.setTotalPrice(totalPrices[i]);
					op.setDiscount(discounts[i]);
					od.setAmount(detailAmounts[i]);
					// 检查是否updates specid
					if (specIds.length == op.getQty()) {
						// 异动原op
						op.setProdSpecId(specIds[i]);
						op.setProdSpecName(specNames[i]);
						op.setProdId(productIds[i]);
						od.setProdSpecId(specIds[i]);
						od.setProdSpecName(specNames[i]);
						od.setProdId(productIds[i]);

					}
					baseMgr.update(op);
					baseMgr.update(od);
				} else {
					OrderProduct opn = new OrderProduct();
					BeanUtils.copyProperties(op, opn);
					opn.setOrderProdId(null);
					opn.setTotalPrice(totalPrices[i]);
					opn.setDiscount(discounts[i]);
					opn.setProdId(productIds[i]);
					opn.setProdSpecId(specIds[i]);
					opn.setProdSpecName(specNames[i]);
					prodSeq = prodSeq + 1;
					opn.setProdSeq(prodSeq);
					opn.setOrderProductDetail(null);
					System.out.println("orderId:" + opn.getOrderId() + "; prodSeq:" + opn.getProdSeq());
					baseMgr.save(opn);

					OrderProductDetail odn = new OrderProductDetail();
					BeanUtils.copyProperties(od, odn);
					odn.setOrderDetailId(null);
					odn.setAmount(detailAmounts[i]);
					odn.setProdId(productIds[i]);
					odn.setProdSpecId(specIds[i]);
					odn.setProdSpecName(specNames[i]);

					odn.setOrderProdId(opn.getOrderProdId());
					odn.setOrderProd(opn);
					odn.setProdSeq(opn.getProdSeq());
					detailSeq = detailSeq + 1;
					odn.setDetailSeq(detailSeq);
					System.out.println("orderId:" + opn.getOrderId() + "; prodSeq:" + opn.getProdSeq() + "; detailSeq:"
							+ odn.getDetailSeq());
					baseMgr.save(odn);

				}
			}

		}
	}

	private void processAddrProblem(Trade trade, Orders order) {
		Object obj = JspUtil.getAddrByOuterAddrMap("yaodian100.tmall.com", trade.getReceiverState(), trade
				.getReceiverCity(), trade.getReceiverDistrict());
		AddrMapping am = null;
		if (obj != null) {
			am = (AddrMapping) obj;
			order.setReceiverProvince(am.getYdProvince());
			order.setReceiverCity(am.getYdCity());
			order.setReceiverArea(am.getYdDistrict());

		} else {
			// // 若找不到对应，则用原始资料，并设为人工改单
			// order.setReceiverProvince(trade.getReceiverState());
			// order.setReceiverCity(trade.getReceiverCity());
			// order.setReceiverArea(trade.getReceiverDistrict());
			String sql = "insert into EC_ADDR_MAPPING_TMP(OUT_PROVINCE, OUT_CITY, OUT_DISTRICT, OUT_ADDR, DOMAIN_SRC) values(?,?,?,?,?)";
			jdbcTemplate.update(sql, trade.getReceiverState(), trade.getReceiverCity(), trade.getReceiverDistrict(), trade
					.getReceiverAddress(), "yaodian100.tmall.com");
			// // 若資料內有的省時，將省字移除
			if (trade.getReceiverState().indexOf("省") > 0) {
				order.setReceiverProvince(trade.getReceiverState().replace("省", ""));
			} else if (trade.getReceiverState().indexOf("内蒙古自治区") > -1) {
				order.setReceiverProvince(trade.getReceiverState().replace("自治区", ""));
			} else if (trade.getReceiverState().indexOf("广西壮族自治区") > -1) {
				order.setReceiverProvince(trade.getReceiverState().replace("壮族自治区", ""));
			} else if (trade.getReceiverState().indexOf("西藏自治区") > -1) {
				order.setReceiverProvince(trade.getReceiverState().replace("自治区", ""));
			} else if (trade.getReceiverState().indexOf("宁夏回族自治区") > -1) {
				order.setReceiverProvince(trade.getReceiverState().replace("回族自治区", ""));
			} else if (trade.getReceiverState().indexOf("新疆维吾尔自治区") > -1) {
				order.setReceiverProvince(trade.getReceiverState().replace("维吾尔自治区", ""));
			} else {
				order.setReceiverProvince(trade.getReceiverState());
			}
			order.setReceiverCity(trade.getReceiverCity());
			// // 若没有区资讯，则以市填入
			if ((trade.getReceiverDistrict() == null) || (trade.getReceiverDistrict().length() == 0)) {
				order.setReceiverArea(trade.getReceiverCity());
			} else {
				order.setReceiverArea(trade.getReceiverDistrict());
			}
		}
		order.setReceiverAddr(trade.getReceiverAddress());
		order.setReceiverZip(trade.getReceiverZip());
		// 再做一次检查
		if ((order.getReceiverProvince() == null) || (order.getReceiverProvince().length() == 0)
				|| (order.getReceiverCity() == null) || (order.getReceiverCity().length() == 0)
				|| (order.getReceiverArea() == null) || (order.getReceiverArea().length() == 0)
				|| (order.getReceiverAddr() == null) || (order.getReceiverAddr().length() == 0)
				|| (order.getReceiverZip() == null) || (order.getReceiverZip().length() == 0)
				|| (order.getReceiverProvince().indexOf("台湾") >= 0) || (order.getReceiverProvince().indexOf("香港") >= 0)
				|| (order.getReceiverProvince().indexOf("澳门") >= 0) || (order.getReceiverProvince().indexOf("海外") >= 0)) {
			// 直接設成人工改單
			order.setOrderSt("05");
		}
	}

	private Orders tradeToOrder(Trade trade, boolean forcePresent, String tradeFrom) {
		Orders order = null;
		try {

			boolean isExist = checkOrderExist(trade);// 检查订单是否已建立

			Member member = memberService.get(menuService.get("SystemValue").getOptions().get("tmall_member").getMemo1());
			/* 加入资料库重覆订单检核 */
			try {
				jdbcTemplate.update("insert into ec_order_outer values (?, ?)", member.getDomainSrc(), trade.getTid()
						.toString());
				isExist = false;
			} catch (Exception e) {
				logger.info("outerOrderId:" + trade.getTid() + " has downloaded already");
				isExist = true;
			}
			// 是否协议退款
			boolean isNeedRefund = isNeedRefund(trade);

			if (!isExist && !isNeedRefund) {

				order = new Orders();

				/* 写入order default资料 */
				order.setPaymentTp("50");// 网上支付
				order.setDomainSrc(member.getDomainSrc());
				order.setChannel_child("");
				order.setClientIp("127.0.0.1");
				Date dead1 = DateUtil.getTodayAddDays(1).getTime();
				order.setDeadline(DateUtil.getLastTimestamp(Calendar.HOUR_OF_DAY, dead1));// 网上支付付款期限24hr
				order.setAllowSplit("N");
				order.setCodFee(BigDecimal.ZERO);
				if (trade.getBuyerMessage() != null) {
					order.setOrderSt("00");

				} else {
					order.setOrderSt("20");
				}
				for (int i = 0; i < trade.getOrders().size(); i++) {
					Order tmallOrder = trade.getOrders().get(i);
					if (tmallOrder.getIsOversold()) {
						// 若为超卖，将订单状态设为09，视进货状况处理
						order.setOrderSt("09");
						break;
					}
				}
				order.setPaymentSt("10");
				order.setOrderType("3");// 外部商城訂單
				order.setPaymentSrc("07");
				order.setPaymentDt(trade.getPayTime());
				order.setCash(BigDecimal.ZERO);

				order.setInvoiceTp("01");
				order.setInvoiceTitle(trade.getInvoiceName());

				/*
				 * 检查地址
				 */
				processAddrProblem(trade, order);
				order.setReceiverPhone(trade.getReceiverPhone());
				order.setReceiverPhoneArea(" ");
				order.setReceiverExt(" ");
				order.setReceiverMobile(trade.getReceiverMobile());
				order.setReceiverEmail(trade.getBuyerEmail());
				order.setMemo("msg:" + trade.getBuyerMessage() + ",memo:" + trade.getBuyerMemo());
				// TODO:拦单
				order.setMemberId(member.getMemberId());
				order.setLoginId(member.getLoginId());
				order.setOuterOrderId(trade.getTid().toString());
				order.setJoinMustPay(new BigDecimal(trade.getPayment()));
				// channel:yaodian100?
				order.setChannel("yaodian100");
				order.setMemberName("tmallUser_" + trade.getBuyerAlipayNo());

				order.setOrderDt(trade.getCreated());
				if ((order.getReceiverEmail() == null) || (order.getReceiverEmail().length() == 0)) {
					order.setReceiverEmail(" ");
				}
				// order.setReceiverEmail("andy.chuang@yaodian100.com");
				order.setReceiverName(trade.getReceiverName());
				// order.setSyncDt(trade.getPayTime());
				// TODO 立即後送
				order.setSyncDt(DateUtil.incrementMinutes(-60).getTime());

				order = orderService.save(order);
				order.setPointAmount(new BigDecimal(trade.getPointFee()).divide(BigDecimal.valueOf(100)).setScale(2,
						BigDecimal.ROUND_DOWN));

				/*
				 * 假定： 1.限时折扣只能立即购买，便不会有多个商品拆折扣的问题 2.运费保险费因不是给商家，故保险费不需算入订单金额 3.商城积分由淘宝承担
				 */
				BigDecimal discount = BigDecimal.valueOf(Float.valueOf(trade.getDiscountFee()));
				int productCount = trade.getOrders().size();
				BigDecimal[] discounts = new BigDecimal[productCount];
				if ((trade != null) && (trade.getOrders() != null)) {
					for (int i = 0; i < trade.getOrders().size(); i++) {
						Order tmallOrder = trade.getOrders().get(i);
						if (i == productCount - 1) {
							int j = i - 1;
							BigDecimal otherDiscount = new BigDecimal(0);
							while (j != -1) {
								otherDiscount = otherDiscount.add(discounts[j]);
								j--;
							}
							discounts[i] = discount.subtract(otherDiscount);
						} else {
							discounts[i] = BigDecimal.valueOf(
									(Float.valueOf(tmallOrder.getTotalFee()) / Float.valueOf(trade.getTotalFee()))
											* discount.floatValue()).setScale(2, BigDecimal.ROUND_HALF_DOWN);
						}
					}
				}
				Specification spec = null;
				Product product = null;
				int i = 1;
				int discountAt = 0;
				if ((trade != null) && (trade.getOrders() != null)) {
					for (Order tmallOrder : trade.getOrders()) {
						if (tmallOrder != null) {
							String orderStatus = tmallOrder.getStatus();
							if ("TRADE_CLOSED_BY_TAOBAO".equals(orderStatus)) {
								// 此商品不发货
								continue;
							}
							// 超卖仍写入订单，状态为09，视进货状况调整
							// if (tmallOrder.getIsOversold() == null || !tmallOrder.getIsOversold()) {// 商品没超卖才可写入
							String outerSpecId = tmallOrder.getOuterSkuId();
							if (outerSpecId == null) {
								outerSpecId = tmallOrder.getOuterIid();
							}

							/*
							 * 若都取不到，则认商品title的#后值 (赠品型的商品)
							 */
							if (outerSpecId == null) {
								String[] titleSplit = tmallOrder.getTitle().split("#");
								if (titleSplit.length > 1) {
									outerSpecId = titleSplit[1];
								}
							}

							spec = productService.getSpecification(Long.parseLong(outerSpecId));
							product = productService.get(spec.getProductId());
							addOrderProduct(tmallOrder, order, product, spec, i, discounts[discountAt++]);
							i++;
							/*
							 * 商品名+仓库编号* +后意指要送赠品 *代表规格随机
							 */
							String productName = tmallOrder.getTitle();
							// 若有活动赠品

							if (productName.indexOf("+") > -1) {
								addOrderPromotionPresent(tmallOrder, order, i);
								i++;
							}
							// } else {
							// throw new Exception("tid:" + trade.getTid() + "商品超卖不写入订单");
							// }
						}
					}
				}
				// if (order.getOrderProduct() == null || order.getOrderProduct().size() == 0) {
				// throw new RuntimeException("order has fatal error!");
				// }
				order.setDiscount(order.getDiscount().add(new BigDecimal(trade.getDiscountFee())));
				order.setShipfare(new BigDecimal(trade.getPostFee()));
				order.setTotalPrice(new BigDecimal(trade.getTotalFee()));
				order.setCash(new BigDecimal(trade.getTotalFee()).subtract(order.getDiscount()).add(order.getShipfare()));
				order.setMustPay(new BigDecimal(trade.getTotalFee()).subtract(order.getDiscount()).add(order.getShipfare()));
				order.setAmount(new BigDecimal(trade.getTotalFee()).subtract(order.getDiscount()));
				if ((tradeFrom != null) && (tradeFrom.indexOf("WAP") >= 0)) {
					// 手机订单强迫写死的赠品
					forcePresent = true;
				}
				if (trade.getPromotionDetails() != null) {
					for (PromotionDetail pd : trade.getPromotionDetails()) {
						if ((pd.getGiftItemName() != null) && (pd.getGiftItemName().length() > 0)) {
							if (pd.getGiftItemName().indexOf("_") < 0) {
								forcePresent = true;
								break;
							}
						}
					}
				}
				// TODO:强迫用设定档来送赠品
				forcePresent = true;
				if (!forcePresent) {
					// 加贈品
					if (trade.getPromotionDetails() != null) {
						for (PromotionDetail pd : trade.getPromotionDetails()) {
							if ((pd.getGiftItemName() != null) && (pd.getGiftItemName().length() > 0)) {
								String[] giftItemNameSplit = pd.getGiftItemName().split("_");
								String[] giftIdSplit = null;
								if (giftItemNameSplit.length > 1) {
									giftIdSplit = giftItemNameSplit[1].split("#");
								}
								String num_iid = giftIdSplit[0];
								Item item = getItem(Long.valueOf(num_iid));
								String[] titleSplit = item.getTitle().split("#");
								String outerSpecId = null;
								// 第二个赠品（因赠品只能设一个，但因涵盖问题可能会到两个赠品）
								String anotherSpecId = null;
								if (titleSplit.length > 1) {
									outerSpecId = titleSplit[1];
								}
								if (titleSplit.length > 2) {
									anotherSpecId = titleSplit[2];
								}

								spec = productService.getSpecification(Long.parseLong(outerSpecId));
								product = productService.get(spec.getProductId());
								addOrderPresent(item.getTitle(), order, product, spec, i);
								i++;
								if (anotherSpecId != null) {
									// 第二个赠品
									Specification anotherSpec = productService.getSpecification(Long.parseLong(anotherSpecId));
									Product anotherProduct = productService.get(anotherSpec.getProductId());
									addOrderPromotionPresent(order, anotherProduct, anotherSpec, i);
									i++;
								}
							}
						}
					}
				} else {
					// 写死的赠品
					// TODO :这一段要再检讨如何避免（因手机订单的giftName不符要求）
					// 加贈品
					// 送小熊
					Option tpf = JspUtil.menuOption("SystemValue", "tmall_present_force");
					Float priceLimit = 999999f;// 预设不送赠品
					String presentName = null;
					if ((tpf != null) && (tpf.getMemo1() != null) && (tpf.getMemo1().length() > 0)) {
						priceLimit = Float.valueOf(tpf.getMemo2());
						presentName = tpf.getMemo1();
					}

					if (order.getMustPay().floatValue() >= priceLimit.floatValue()) {
						if (true) {
							String bearName = presentName;
							String[] titleSplit = bearName.split("#");
							String outerSpecId = null;
							// 第二个赠品（因赠品只能设一个，但因涵盖问题可能会到两个赠品）
							String anotherSpecId = null;
							if (titleSplit.length > 1) {
								outerSpecId = titleSplit[1];
							}
							if (titleSplit.length > 2) {
								anotherSpecId = titleSplit[2];
							}

							spec = productService.getSpecification(Long.parseLong(outerSpecId));
							product = productService.get(spec.getProductId());
							addOrderPresent(bearName, order, product, spec, i);
							i++;
							if (anotherSpecId != null) {
								// 第二个赠品
								Specification anotherSpec = productService.getSpecification(Long.parseLong(anotherSpecId));
								Product anotherProduct = productService.get(anotherSpec.getProductId());
								addOrderPromotionPresent(order, anotherProduct, anotherSpec, i);
								i++;
							}
						}
						// }
					} else
					// 大于0元送购物袋

					if (order.getMustPay().floatValue() > 0) {
						Option tpf2 = JspUtil.menuOption("SystemValue", "tmall_present_force0");
						if ((tpf2 != null) && (tpf2.getMemo1() != null) && (tpf2.getMemo1().length() > 0)) {
							String presentName2 = tpf2.getMemo1();

							String bagName = presentName2;
							String[] titleSplit = bagName.split("#");
							String outerSpecId = null;

							if (titleSplit.length > 1) {
								outerSpecId = titleSplit[1];
							}

							spec = productService.getSpecification(Long.parseLong(outerSpecId));
							product = productService.get(spec.getProductId());
							addOrderPresent(bagName, order, product, spec, i);
							i++;
						}
					}
				}
				// order.setDiscount(order.getDiscount().add(
				// new BigDecimal(trade.getDiscountFee()).add((BigDecimal.valueOf(trade.getPointFee()).divide(BigDecimal
				// .valueOf(100))))));

				// 添加保证卡商品
				addGuaranteeProduct(order, i);
				// 更新订单的joinorders
				order.setJoinOrders(order.getOrderId());

				orderService.update(order);
				if ((order != null) && "00".equals(order.getOrderSt())) {
					// 淘宝审核工单
					csService
							.createTmallWO(order.getOrderId(), "外部单号：" + order.getOrderId() + ";买家备注：" + trade.getBuyerMessage());
				}
				// 12／19上
				// orderService.calcOrderProduct(order);
				// orderService.calcOrderCash(order);
				// orderService.update(order);
				Orders calcOrder = orderService.getOrder(order.getOrderId());
				calcOrder = orderService.calcOrderProduct(calcOrder);
				calcOrder = orderService.calcOrderCash(calcOrder);
				orderService.update(calcOrder);
				logService.save(this.getClass().getName(), "createOrderWithPay", new Object[] { order });
				// 上传备注
				TradeMemoAddRequest req = new TradeMemoAddRequest();
				req.setTid(trade.getTid());
				req.setMemo(order.getOrderId());
				TaobaoResponse res = executeHttp(req);
				if ((res == null) || !res.isSuccess()) {
					logger.error("add trade memo fail, tid:" + trade.getTid() + ", order: " + order.getOrderId());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("trade to order fail, tid:" + trade.getTid(), e);
			throw new RuntimeException(e);
		}

		return order;
	}

	private Orders interceptOrder(Orders order, String tid) {
		// 拦单
		Map<String, Object> map = interceptOrderService.findOrder(tid, "yaodian100.tmall.com", "1");
		if (map.size() > 0) {
			order.setOrderSt("05");
			order.setMemo(order.getMemo() + ",拦单原因：" + map.get("memo").toString());
		}
		return order;
	}

	private boolean checkOrderSuccess(Trade trade, Orders order) {
		boolean isOrderSuccess = true;
		// 检查订单金额
		BigDecimal totalFee = new BigDecimal(trade.getTotalFee());
		if (totalFee.floatValue() != order.getTotalPrice().floatValue()) {
			isOrderSuccess = false;
		}
		// 检查商品
		for (Order to : trade.getOrders()) {
			boolean isExist = false;
			for (OrderProduct op : order.getOrderProduct()) {
				if (to.getOuterSkuId().equals(op.getProdSpecId())) {
					isExist = true;
					break;
				}
			}
			if (!isExist) {
				isOrderSuccess = false;
				break;
			}
		}
		if (trade.getPromotionDetails() != null) {
			for (PromotionDetail pd : trade.getPromotionDetails()) {
				if ((pd.getGiftItemName() != null) && (pd.getGiftItemName().length() > 0)) {
					String[] giftItemNameSplit = pd.getGiftItemName().split("_");
					String[] giftIdSplit = null;
					if (giftItemNameSplit.length > 1) {
						giftIdSplit = giftItemNameSplit[1].split("#");
					}
					String num_iid = giftIdSplit[0];
					Item item = getItem(Long.valueOf(num_iid));
					String[] titleSplit = item.getTitle().split("#");
					String outerSpecId = null;
					// 第二个赠品（因赠品只能设一个，但因涵盖问题可能会到两个赠品）
					String anotherSpecId = null;
					if (titleSplit.length > 1) {
						outerSpecId = titleSplit[1];
					}
					if (titleSplit.length > 2) {
						anotherSpecId = titleSplit[2];
					}
					for (OrderProduct op : order.getOrderProduct()) {
						if (op.getProdSpecId().equals(outerSpecId)) {

							break;
						}
						isOrderSuccess = false;
					}
					if ((anotherSpecId != null) && (anotherSpecId.length() > 0)) {
						for (OrderProduct op : order.getOrderProduct()) {
							if (op.getProdSpecId().equals(outerSpecId)) {
								break;
							}
							isOrderSuccess = false;
						}
					}
				}

			}
		}

		if (!isOrderSuccess) {
			order.setOrderSt("09");
		}
		return false;
	}

	private boolean checkOrderExist(String outerOrderId) {
		Long result = baseMgr.countByHql("from Orders where outerOrderId=?", new Object[] { outerOrderId });
		if (result > 0) {
			return true;
		}
		return false;
	}

	private Orders recordToOrder(Map<String, Object> record, List<Map<String, Object>> detailRecords) {
		Orders order = null;
		String outerOrderId = (String) record.get("outerOrderId");
		try {
			// order = checkOrderExist(trade);// 检查订单是否已建立
			boolean isExist = checkOrderExist((String) record.get("outerOrderId"));
			if (isExist) {
				System.out.println("outerOrderId:" + (String) record.get("outerOrderId") + " is exist!");
			}
			if (!isExist) {
				Member member = memberService.get(menuService.get("SystemValue").getOptions().get("tmall_member").getMemo1());
				order = new Orders();
				/* 写入order default资料 */
				order.setPaymentTp("50");// 网上支付
				order.setDomainSrc(member.getDomainSrc());
				order.setChannel_child("");
				order.setClientIp("127.0.0.1");
				Date dead1 = DateUtil.getTodayAddDays(1).getTime();
				order.setDeadline(DateUtil.getLastTimestamp(Calendar.HOUR_OF_DAY, dead1));// 网上支付付款期限24hr
				order.setAllowSplit("N");
				order.setCodFee(BigDecimal.ZERO);

				order.setOrderSt("00");

				order.setPaymentSt("10");
				order.setOrderType("3");// 外部商城訂單
				order.setPaymentSrc("07");
				order.setPaymentDt((Date) record.get("paymentDate"));
				order.setCash(BigDecimal.ZERO);

				order.setInvoiceTp("01");
				String state = (String) record.get("receiverProvince");
				String city = (String) record.get("receiverCity");
				String area = (String) record.get("receiverArea");
				String addr = (String) record.get("receiverAddr");
				// 若資料內有的省時，將省字移除
				if (state.indexOf("省") > 0) {
					order.setReceiverProvince(state.replace("省", ""));
				} else if (state.indexOf("内蒙古自治区") > -1) {
					order.setReceiverProvince(state.replace("自治区", ""));
				} else if (state.indexOf("广西壮族自治区") > -1) {
					order.setReceiverProvince(state.replace("壮族自治区", ""));
				} else if (state.indexOf("西藏自治区") > -1) {
					order.setReceiverProvince(state.replace("自治区", ""));
				} else if (state.indexOf("宁夏回族自治区") > -1) {
					order.setReceiverProvince(state.replace("回族自治区", ""));
				} else if (state.indexOf("新疆维吾尔自治区") > -1) {
					order.setReceiverProvince(state.replace("维吾尔自治区", ""));
				} else {
					order.setReceiverProvince(state);
				}
				order.setReceiverCity(city);
				// 若没有区资讯，则以市填入
				if ((area == null) || (area.length() == 0)) {
					order.setReceiverArea(city);
				} else {
					order.setReceiverArea(area);
				}
				order.setReceiverAddr(addr);
				order.setReceiverZip((String) record.get("receiverZip"));
				order.setReceiverPhone((String) record.get("receiverPhone"));
				order.setReceiverPhoneArea(" ");
				order.setReceiverExt(" ");
				order.setReceiverMobile((String) record.get("receiverMobile"));
				order.setReceiverEmail(" ");
				order.setMemo("msg:" + (String) record.get("memo") + ",memo:");
				order.setMemberId(member.getMemberId());
				order.setLoginId(member.getLoginId());
				order.setOuterOrderId((String) record.get("outerOrderId"));
				order.setJoinMustPay((BigDecimal) record.get("joinMustPay"));
				order.setMustPay((BigDecimal) record.get("mustPay"));
				// channel:yaodian100?
				order.setChannel("yaodian100");
				order.setMemberName(member.getName());
				if (order.getMemberName() == null) {
					order.setMemberName("tmallUser");
				}
				order.setOrderDt((Date) record.get("orderDate"));
				if (order.getReceiverEmail() == null) {
					order.setReceiverEmail(" ");
				}
				// order.setReceiverEmail("andy.chuang@yaodian100.com");
				order.setReceiverName((String) record.get("receiverName"));
				order.setSyncDt((Date) record.get("paymentDate"));

				order = orderService.save(order);
				order.setPointAmount((BigDecimal) record.get("pointAmount"));
				// 总货款
				BigDecimal orderAmount = (BigDecimal) record.get("amount");
				// 订单总金额
				BigDecimal orderTotalPrice = BigDecimal.ZERO;
				for (int i = 0; i < detailRecords.size(); i++) {
					Map<String, Object> detailRecord = detailRecords.get(i);
					BigDecimal unitPrice = (BigDecimal) detailRecord.get("unitPrice");
					BigDecimal qty = (BigDecimal) detailRecord.get("qty");
					BigDecimal productTotalPrice = unitPrice.multiply(qty);
					orderTotalPrice = orderTotalPrice.add(productTotalPrice);
				}
				BigDecimal totalDiscount = orderTotalPrice.subtract(orderAmount);
				order.setDiscount(totalDiscount);

				/*
				 * 假定： 1.限时折扣只能立即购买，便不会有多个商品拆折扣的问题 2.运费保险费因不是给商家，故保险费不需算入订单金额 3.商城积分由淘宝承担
				 */
				BigDecimal discount = totalDiscount;
				int productCount = detailRecords.size();
				BigDecimal[] discounts = new BigDecimal[productCount];
				for (int i = 0; i < detailRecords.size(); i++) {
					Map<String, Object> detailRecord = detailRecords.get(i);
					BigDecimal unitPrice = (BigDecimal) detailRecord.get("unitPrice");
					BigDecimal qty = (BigDecimal) detailRecord.get("qty");
					BigDecimal productTotalPrice = unitPrice.multiply(qty);
					if (i == productCount - 1) {
						int j = i - 1;
						BigDecimal otherDiscount = new BigDecimal(0);
						while (j != -1) {
							otherDiscount = otherDiscount.add(discounts[j]);
							j--;
						}
						discounts[i] = discount.subtract(otherDiscount);
					} else {
						discounts[i] = BigDecimal.valueOf(
								(productTotalPrice.floatValue() / orderTotalPrice.floatValue()) * discount.floatValue()).setScale(2,
								BigDecimal.ROUND_HALF_DOWN);
					}
				}
				Specification spec = null;
				Product product = null;
				int i = 1;
				// if (trade != null && trade.getOrders() != null) {
				for (Map<String, Object> detailRecord : detailRecords) {
					if (detailRecord != null) {
						// TODO:超卖问题！！
						if (true) {
							String outerSpecId = (String) detailRecord.get("specId");

							/*
							 * 若都取不到，则认商品title的#后值 (赠品型的商品)
							 */
							String productName = (String) detailRecord.get("productName");
							if (outerSpecId == null) {
								String[] titleSplit = productName.split("#");
								if (titleSplit.length > 1) {
									outerSpecId = titleSplit[1];
								}
							}

							spec = productService.getSpecification(Long.parseLong(outerSpecId));
							product = productService.get(spec.getProductId());
							addOrderProduct(detailRecord, order, product, spec, i, discounts[i - 1]);
							i++;
							/*
							 * 商品名+仓库编号* +后意指要送赠品 *代表规格随机
							 */
							// String productName = tmallOrder.getTitle();
							// 若有活动赠品

							if (productName.indexOf("+") > -1) {
								addOrderPromotionPresent(detailRecord, order, i);
								i++;
							}
						} else {
							throw new Exception("tid:" + outerOrderId + "商品超卖不写入订单");
						}
					}
				}
				// }
				// 加贈品
				// 大于159送小熊
				if (order.getMustPay().floatValue() >= 15900) {
					// for (PromotionDetail pd : trade.getPromotionDetails()) {

					if (true) {
						// String[] giftItemNameSplit = pd.getGiftItemName().split("_");
						// String[] giftIdSplit = null;
						// if (giftItemNameSplit.length > 1) {
						// giftIdSplit = giftItemNameSplit[1].split("#");
						// }
						// String num_iid = "12895434192";
						// Item item = getItem(Long.valueOf(num_iid));
						String bearName = "【YD100】幸运玩偶小熊购物袋迷彩色#0000241480#0000217019";
						String[] titleSplit = bearName.split("#");
						String outerSpecId = null;
						// 第二个赠品（因赠品只能设一个，但因涵盖问题可能会到两个赠品）
						String anotherSpecId = null;
						if (titleSplit.length > 1) {
							outerSpecId = titleSplit[1];
						}
						if (titleSplit.length > 2) {
							anotherSpecId = titleSplit[2];
						}

						spec = productService.getSpecification(Long.parseLong(outerSpecId));
						product = productService.get(spec.getProductId());
						addOrderPresent(bearName, order, product, spec, i);
						i++;
						if (anotherSpecId != null) {
							// 第二个赠品
							Specification anotherSpec = productService.getSpecification(Long.parseLong(anotherSpecId));
							Product anotherProduct = productService.get(anotherSpec.getProductId());
							addOrderPromotionPresent(order, anotherProduct, anotherSpec, i);
							i++;
						}
					}
					// }
				} else
				// 大于0元送购物袋
				if (order.getMustPay().floatValue() > 0) {
					String bagName = "【YD100】2011環保購物袋棕色 #0000217019";
					String[] titleSplit = bagName.split("#");
					String outerSpecId = null;

					if (titleSplit.length > 1) {
						outerSpecId = titleSplit[1];
					}

					spec = productService.getSpecification(Long.parseLong(outerSpecId));
					product = productService.get(spec.getProductId());
					addOrderPresent(bagName, order, product, spec, i);
					i++;
				}

				// order.setDiscount(order.getDiscount().add(
				// new BigDecimal(trade.getDiscountFee()).add((BigDecimal.valueOf(trade.getPointFee()).divide(BigDecimal
				// .valueOf(100))))));
				order.setDiscount(totalDiscount);
				order.setShipfare((BigDecimal) record.get("shipFare"));
				order.setTotalPrice(orderTotalPrice);
				order.setCash((BigDecimal) record.get("cash"));
				order.setMustPay((BigDecimal) record.get("mustPay"));
				order.setAmount((BigDecimal) record.get("amount"));

				// 添加保证卡商品
				addGuaranteeProduct(order, i);
				// 更新订单的joinorders
				order.setJoinOrders(order.getOrderId());
				orderService.update(order);
				logService.save(this.getClass().getName(), "createOrderWithPay", new Object[] { order });
				// // 上传备注
				// TradeMemoAddRequest req = new TradeMemoAddRequest();
				// req.setTid();
				// req.setMemo(order.getOrderId());
				// TaobaoResponse res = executeHttp(req, null);
				// if (res == null || !res.isSuccess()) {
				// logger.error("add trade memo fail, tid:" + trade.getTid() + ", order: " + order.getOrderId());
				// }
			}
		} catch (Exception e) {
			logger.error("outer_order_id:" + outerOrderId + " is exist!!");
			// logger.error("trade to order fail, tid:" + trade.getTid(), e);
			// throw new RuntimeException(e);
		}
		return order;
	}

	/**
	 * 检查订单是否已存在
	 * 
	 * @param trade
	 * @return
	 */
	boolean checkOrderExist(Trade trade) {
		Long count = baseMgr.countByHql("from Orders where outerOrderId=?", new Object[] { trade.getTid().toString() });
		if ((count != null) && (count > 0)) {
			return true;
		}
		return false;
		// CommonCriteria crit = new CommonCriteria();
		// crit.addEq("outerOrderId", trade.getTid().toString());
		// List<Orders> existOrders = orderService.getList(0, 1, crit, null);
		// if (null != existOrders && existOrders.size() > 0) {
		// logger.error("trade tid is exist :" + trade.getTid() + ", memo: " + trade.getSellerMemo());
		// return existOrders.get(0);
		// } else {
		// return null;
		// }
	}

	OrderProduct addOrderProduct(Map<String, Object> detailRecord, Orders order, Product product, Specification spec,
			int i, BigDecimal discount) {
		OrderProduct entityProd = new OrderProduct();
		entityProd.setCategoryPath(product.getMainCategoryPath());
		entityProd.setEcCost(product.getProductCost());
		entityProd.setPmId(product.getPmID());
		entityProd.setProdId(product.getProductId());
		entityProd.setProdName((String) detailRecord.get("productName"));
		entityProd.setProdSeq(i);
		entityProd.setProdSpecId(spec.getSpecificationId().toString());
		entityProd.setProdSpecName((String) detailRecord.get("productSpecName"));
		if (entityProd.getProdSpecName() == null) {
			entityProd.setProdSpecName(" ");
		}
		entityProd.setProdTp(Product.PRODUCT_TYPE.MAIN.getValue());
		entityProd.setQty(((BigDecimal) detailRecord.get("qty")).intValue());
		entityProd.setUnitPrice((BigDecimal) detailRecord.get("unitPrice"));
		// 因amount＝totalPrice-coupon-discount
		// entityProd.setTotalPrice(new BigDecimal(tmallOrder.getTotalFee()).setScale(1, BigDecimal.ROUND_HALF_DOWN));
		entityProd.setTotalPrice(entityProd.getUnitPrice().multiply(BigDecimal.valueOf(entityProd.getQty())));

		entityProd.setDiscount(new BigDecimal(discount.floatValue()));
		// order.setDiscount(order.getDiscount().add(BigDecimal.valueOf(Float.valueOf(tmallOrder.getDiscountFee()))));
		entityProd.setReturnRule(product.getReturnRule());
		entityProd.setOrder(order);
		entityProd.setOrderId(order.getOrderId());
		User user = (User) baseMgr.get(User.class, product.getPmID());
		entityProd.setPmGroup(user.getGroupName());
		orderService.saveOrderProd(entityProd);
		addOrderProductDetail(null, order, entityProd, product);
		return entityProd;
	}

	/**
	 * 新增订单商品
	 * 
	 * @param tmallOrder
	 * @param order
	 * @param product
	 * @param spec
	 * @param i
	 * @return
	 */
	OrderProduct addOrderProduct(Order tmallOrder, Orders order, Product product, Specification spec, int i,
			BigDecimal discount) {
		OrderProduct entityProd = new OrderProduct();
		// // 加入外部商品编号
		// entityProd.setOuterProdId(String.valueOf(tmallOrder.getNumIid()));
		entityProd.setCategoryPath(product.getMainCategoryPath());
		entityProd.setEcCost(product.getProductCost());
		entityProd.setPmId(product.getPmID());
		entityProd.setProdId(product.getProductId());
		entityProd.setProdName(tmallOrder.getTitle());
		entityProd.setProdSeq(i);
		entityProd.setProdSpecId(spec.getSpecificationId().toString());
		entityProd.setProdSpecName(tmallOrder.getSkuPropertiesName());
		if (entityProd.getProdSpecName() == null) {
			entityProd.setProdSpecName(" ");
		}
		entityProd.setProdTp(Product.PRODUCT_TYPE.MAIN.getValue());
		entityProd.setQty(tmallOrder.getNum().intValue());
		entityProd.setUnitPrice(new BigDecimal(tmallOrder.getPrice()));
		// 因amount＝totalPrice-coupon-discount
		// entityProd.setTotalPrice(new BigDecimal(tmallOrder.getTotalFee()).setScale(1, BigDecimal.ROUND_HALF_DOWN));
		entityProd.setTotalPrice(entityProd.getUnitPrice().multiply(BigDecimal.valueOf(entityProd.getQty())));

		entityProd.setDiscount(new BigDecimal(Float.valueOf(tmallOrder.getDiscountFee()) + discount.floatValue()));
		order.setDiscount(order.getDiscount().add(BigDecimal.valueOf(Float.valueOf(tmallOrder.getDiscountFee()))));
		entityProd.setReturnRule(product.getReturnRule());
		entityProd.setOrder(order);
		entityProd.setOrderId(order.getOrderId());
		User user = (User) baseMgr.get(User.class, product.getPmID());
		entityProd.setPmGroup(user.getGroupName());
		orderService.saveOrderProd(entityProd);
		addOrderProductDetail(tmallOrder, order, entityProd, product);
		return entityProd;
	}

	OrderProduct addOrderPromotionPresent(Map<String, Object> detailRecord, Orders order, int i) {
		String productName = (String) detailRecord.get("productName");
		OrderProduct op = null;
		String specId = StringUtils.split(productName, "+")[1];
		// *代表规格随机
		if (specId.indexOf("*") > -1) {
			specId = specId.replace("*", "");
			// 回头找所有该商品的规格
			Specification spec = (Specification) baseMgr.get(Specification.class, Long.valueOf(specId));
			Product product = (Product) baseMgr.get(Product.class, spec.getProductId());
			Object[] result = baseMgr.queryByHql(
					"from SpecificationInventory where productId=? and (availableInventory - soldInventory + cancelInventory)>?",
					new Object[] { spec.getProductId(), Integer.valueOf(0) });
			if ((result == null) || (result.length == 0)) {
				// 若没有任何有库存的，用默认的
				op = addOrderPromotionPresent(order, product, spec, i);

			} else {
				// 乱数取spec
				Random ran = new Random();
				int rowAt = ran.nextInt(result.length);
				SpecificationInventory si = (SpecificationInventory) result[rowAt];
				spec = si.getSpecification();
				op = addOrderPromotionPresent(order, product, spec, i);
			}
		} else {
			Specification spec = (Specification) baseMgr.get(Specification.class, Long.valueOf(specId));
			Product product = (Product) baseMgr.get(Product.class, spec.getProductId());
			op = addOrderPromotionPresent(order, product, spec, i);
		}
		return op;
	}

	OrderProduct addOrderPromotionPresent(Order to, Orders order, int i) {
		String productName = to.getTitle();
		OrderProduct op = null;
		String specId = StringUtils.split(productName, "+")[1];
		// *代表规格随机
		if (specId.indexOf("*") > -1) {
			specId = specId.replace("*", "");
			// 回头找所有该商品的规格
			Specification spec = (Specification) baseMgr.get(Specification.class, Long.valueOf(specId));
			Product product = (Product) baseMgr.get(Product.class, spec.getProductId());
			Object[] result = baseMgr.queryByHql(
					"from SpecificationInventory where productId=? and (availableInventory - soldInventory + cancelInventory)>?",
					new Object[] { spec.getProductId(), Integer.valueOf(0) });
			if ((result == null) || (result.length == 0)) {
				// 若没有任何有库存的，用默认的
				op = addOrderPromotionPresent(order, product, spec, i);

			} else {
				// 乱数取spec
				Random ran = new Random();
				int rowAt = ran.nextInt(result.length);
				SpecificationInventory si = (SpecificationInventory) result[rowAt];
				spec = si.getSpecification();
				op = addOrderPromotionPresent(order, product, spec, i);
			}
		} else {
			Specification spec = (Specification) baseMgr.get(Specification.class, Long.valueOf(specId));
			Product product = (Product) baseMgr.get(Product.class, spec.getProductId());
			op = addOrderPromotionPresent(order, product, spec, i);
		}
		return op;
	}

	/**
	 * 行销赠品加入
	 * 
	 * @param order
	 * @param product
	 * @param spec
	 * @param i
	 * @return
	 */
	OrderProduct addOrderPromotionPresent(Orders order, Product product, Specification spec, int i) {
		OrderProduct entityProd = new OrderProduct();
		entityProd.setCategoryPath(product.getMainCategoryPath());
		entityProd.setEcCost(product.getProductCost());
		entityProd.setPmId(product.getPmID());
		entityProd.setProdId(product.getProductId());
		entityProd.setProdName(product.getProductName());
		entityProd.setProdSeq(i);
		entityProd.setProdSpecId(spec.getSpecificationId().toString());
		entityProd.setProdSpecName(spec.getSpecificationName());
		entityProd.setProdTp(Product.PRODUCT_TYPE.PRESENT.getValue());
		entityProd.setQty(1);
		entityProd.setUnitPrice(new BigDecimal(0));
		entityProd.setTotalPrice(new BigDecimal(0));
		entityProd.setDiscount(new BigDecimal(0));
		entityProd.setReturnRule(product.getReturnRule());
		entityProd.setOrder(order);
		entityProd.setOrderId(order.getOrderId());
		User user = (User) baseMgr.get(User.class, product.getPmID());
		entityProd.setPmGroup(user.getGroupName());
		orderService.saveOrderProd(entityProd);
		addOrderProductDetail(null, order, entityProd, product);
		return entityProd;
	}

	/**
	 * 新增赠品
	 * 
	 * @param item
	 * @param order
	 * @param product
	 * @param spec
	 * @param i
	 * @return
	 */
	OrderProduct addOrderPresent(String presentName, Orders order, Product product, Specification spec, int i) {
		OrderProduct entityProd = new OrderProduct();
		entityProd.setCategoryPath(product.getMainCategoryPath());
		entityProd.setEcCost(product.getProductCost());
		entityProd.setPmId(product.getPmID());
		entityProd.setProdId(product.getProductId());
		entityProd.setProdName(presentName);
		entityProd.setProdSeq(i);
		entityProd.setProdSpecId(spec.getSpecificationId().toString());
		entityProd.setProdSpecName(" ");
		entityProd.setProdTp(Product.PRODUCT_TYPE.PRESENT.getValue());
		entityProd.setQty(1);
		entityProd.setUnitPrice(new BigDecimal(0));
		entityProd.setTotalPrice(new BigDecimal(0));
		entityProd.setDiscount(new BigDecimal(0));
		entityProd.setReturnRule(product.getReturnRule());
		entityProd.setOrder(order);
		entityProd.setOrderId(order.getOrderId());
		User user = (User) baseMgr.get(User.class, product.getPmID());
		entityProd.setPmGroup(user.getGroupName());
		orderService.saveOrderProd(entityProd);
		addOrderProductDetail(null, order, entityProd, product);
		return entityProd;
	}

	/**
	 * 新增订单商品明细
	 * 
	 * @param order
	 * @param entityProd
	 * @param product
	 * @return
	 */
	OrderProductDetail addOrderProductDetail(Order tmallOrder, Orders order, OrderProduct entityProd, Product product) {
		OrderProductDetail entityDetail = new OrderProductDetail();
		if (tmallOrder != null) {
			entityDetail.setOuterCid(String.valueOf(tmallOrder.getCid()));
			entityDetail.setOuterProdId(String.valueOf(tmallOrder.getNumIid()));
			entityDetail.setOuterSkuId(tmallOrder.getSkuId());
		}
		entityDetail.setAmount(entityProd.getUnitPrice().multiply(BigDecimal.valueOf(entityProd.getQty())));
		entityDetail.setDetailSeq(entityProd.getProdSeq());
		entityDetail.setDetailTp(entityProd.getProdTp());
		entityDetail.setEcCost(entityProd.getEcCost());
		entityDetail.setProdId(entityProd.getProdId());
		entityDetail.setProdName(entityProd.getProdName());
		entityDetail.setProdSeq(entityProd.getProdSeq());
		entityDetail.setProdSpecId(entityProd.getProdSpecId());
		entityDetail.setProdSpecName(entityProd.getProdSpecName());
		entityDetail.setQty(entityProd.getQty());
		entityDetail.setReturnRule(entityProd.getReturnRule());
		entityDetail.setUnitPrice(entityProd.getUnitPrice());
		entityDetail.setUnitVolumeWeight(product.getProductVolume());
		entityDetail.setUnitWeight(product.getProductWeight());
		if (StringUtils.isBlank(product.getCanUseCod())) {
			entityDetail.setCanUseCod("Y");
		} else {
			entityDetail.setCanUseCod(product.getCanUseCod());
		}
		if ((product.getProductType() == 1) && (null != product.getExpectShipDate())) {
			entityDetail.setExpectShipDate(EcConstant.PATTERN_DATE_FORMAT.format(product.getExpectShipDate()));
		}
		if (product.getProductType() != 1) {
			// BO/订制商品供备货时间
			// 轉單商品
			SupplierApply sp = supplierApplyService.get(product.getSupplierId());
			if (StringUtils.equals(product.getIsScm(), "Y")) {
				// 有訂制天數
				if (StringUtils.equals(product.getUseDeliveryDay(), "Y")) {
					entityDetail.setDeliveryDay(product.getDeliveryDay());
				}
			}
			// BO商品
			if (StringUtils.equals(product.getIsScm(), "B")) {
				// 有訂制天數
				if (StringUtils.equals(product.getUseDeliveryDay(), "Y")) {
					entityDetail.setDeliveryDay(product.getDeliveryDay());
				} else {
					if ((null != sp) && (null != sp.getBoToWHDate())) {
						entityDetail.setBoToWhDate(sp.getBoToWHDate());
					}
				}
			}
		}
		entityDetail.setVendId(product.getSupplierId());
		entityDetail.setOrderProd(entityProd);
		entityDetail.setOrderId(order.getOrderId());
		entityDetail.setOrderProdId(entityProd.getOrderProdId());
		entityDetail.setOrder(order);
		orderService.saveOrderDetail(entityDetail);
		return entityDetail;
	}

	/**
	 * 新增保证卡商品
	 * 
	 * @param tmallOrder
	 * @param i
	 * @return
	 */
	OrderProduct addGuaranteeProduct(Orders order, int i) {
		OrderProduct entityProd = new OrderProduct();
		Product product = productService.get(menuService.get("SystemValue").getOptions().get("guarantee_product_id")
				.getMemo1());
		Specification spec = product.getSpecifications().get(0);
		entityProd.setCategoryPath(product.getMainCategoryPath());
		entityProd.setEcCost(product.getProductCost());
		entityProd.setPmId(product.getPmID());
		entityProd.setProdId(product.getProductId());
		entityProd.setProdName(product.getProductName());
		entityProd.setProdSeq(i);
		entityProd.setProdSpecId(spec.getSpecificationId().toString());
		entityProd.setProdSpecName(spec.getSpecificationName());
		entityProd.setProdTp(Product.PRODUCT_TYPE.PRESENT.getValue());
		entityProd.setQty(1);
		entityProd.setUnitPrice(BigDecimal.ZERO);
		entityProd.setTotalPrice(BigDecimal.ZERO);
		entityProd.setDiscount(BigDecimal.ZERO);
		entityProd.setReturnRule(product.getReturnRule());
		entityProd.setOrder(order);
		entityProd.setOrderId(order.getOrderId());
		User user = (User) baseMgr.get(User.class, product.getPmID());
		entityProd.setPmGroup(user.getGroupName());
		orderService.saveOrderProd(entityProd);
		addOrderProductDetail(null, order, entityProd, product);
		return entityProd;
	}

	/*
	 * 上傳備註
	 * 
	 * @see com.yaodian100.ec.tmall.service.TmallService#tradesMemoAdd(java.util.Date, java.util.Date)
	 */
	@Override
	public int tradesMemoAdd(Date start, Date end) {
		CommonCriteria crit = new CommonCriteria();
		crit.addNe("outerOrderId", null);
		crit.addEq("memo", null);// 找订单没写备注的
		if (null == start) {
			crit.addGe("startDate", DateUtil.getTodayAddDays(-1));
		} else {
			crit.addGe("startDate", start);
		}
		if (null == end) {
			crit.addLe("endDate", DateUtil.getToday());
		} else {
			crit.addGe("endDate", end);
		}
		List<Orders> result = orderService.getList(0, -1, crit, new String[] { "createDate" });
		if ((null != result) && (result.size() > 0)) {
			for (Orders order : result) {
				TradeMemoAddRequest req = new TradeMemoAddRequest();
				req.setTid(Long.parseLong(order.getOuterOrderId()));
				req.setMemo(order.getOrderId());
				TaobaoResponse res = executeHttp(req);
				if ((res == null) || !res.isSuccess()) {
					logger.error("add trade memo fail, tid:" + order.getOuterOrderId() + ", order: " + order.getOrderId());
				}
			}
		}
		return result.size();
	}

	/*
	 * 全量下载
	 * 
	 * @see com.yaodian100.ec.tmall.service.TmallService#getTrades(java.util.Date, java.util.Date, java.lang.String, int)
	 */
	@Override
	@Transactional(readOnly = false)
	public List<Orders> getTrades(Date start, Date end, String status, int page) {
		TradesSoldGetRequest req = new TradesSoldGetRequest();
		req.setFields("tid,trade_from");
		// .setFields("promotion,promotion_details,seller_nick,buyer_nick,title,type,created,tid,seller_rate,buyer_rate,status,payment,discount_fee,adjust_fee,post_fee,total_fee,pay_time,end_time,modified,consign_time,buyer_obtain_point_fee,point_fee,real_point_fee,received_payment,commission_fee,pic_path,num_iid,num,price,cod_fee,cod_status,shipping_type,receiver_name,receiver_state,receiver_city,receiver_district,receiver_address,receiver_zip,receiver_mobile,receiver_phone,orders.title, orders.pic_path, orders.price, orders.num, orders.num_iid, orders.sku_id, orders.refund_status, orders.status, orders.oid, orders.total_fee, orders.payment, orders.discount_fee, orders.adjust_fee, orders.sku_properties_name, orders.item_meal_name, orders.buyer_rate, orders.seller_rate, orders.outer_iid, orders.outer_sku_id, orders.refund_id, orders.seller_type");
		if (start == null) {
			req.setStartCreated(DateUtil.getFirstTimestamp(Calendar.DAY_OF_MONTH, new Date()));
		} else {
			req.setStartCreated(start);
		}
		if (end == null) {
			req.setEndCreated(DateUtil.getLastTimestamp(Calendar.DAY_OF_MONTH, new Date()));
		} else {
			req.setEndCreated(end);
		}
		if (StringUtils.isBlank(status)) {
			req.setStatus("WAIT_SELLER_SEND_GOODS");
		} else {
			req.setStatus(status);
		}
		if (page > 0) {
			req.setPageNo(Long.valueOf(page));
		}

		List<Orders> result = new ArrayList();
		TradesSoldGetResponse res = (TradesSoldGetResponse) executeHttp(req);
		if ((res != null) && res.isSuccess() && (res.getTrades() != null)) {
			for (Trade trade : res.getTrades()) {
				try {
					boolean isExist = checkOrderExist(String.valueOf(trade.getTid()));
					// Orders order = tradeToOrder(trade);
					if (!isExist) {
						Orders order = getTradeAndSaveToOrder(String.valueOf(trade.getTid()), trade.getTradeFrom());
						if (null != order) {
							result.add(order);
						}
					} else {
						logger.warn("tid:" + trade.getTid() + " was downloaded!");
					}

				} catch (Exception e) {
					// 不正常单避开
					e.printStackTrace();
					throw new RuntimeException();
				}
			}
		}
		return result;
	}

	/*
	 * 增量下载
	 * 
	 * @see com.yaodian100.ec.tmall.service.TmallService#tradesSoldIncrementGet(java.util.Date, java.util.Date,
	 * java.lang.String)
	 */
	public Integer tradesSoldIncrementGet(Date start, Date end, String status, String[] skipList, Integer page,
			Integer pageSize) {
		TradesSoldIncrementGetRequest req = new TradesSoldIncrementGetRequest();
		req.setFields("tid,trade_from");
		// .setFields("promotion,promotion_details,seller_nick,buyer_nick,title,type,created,tid,seller_rate,buyer_rate,status,payment,discount_fee,adjust_fee,post_fee,total_fee,pay_time,end_time,modified,consign_time,buyer_obtain_point_fee,point_fee,real_point_fee,received_payment,commission_fee,pic_path,num_iid,num,price,cod_fee,cod_status,shipping_type,receiver_name,receiver_state,receiver_city,receiver_district,receiver_address,receiver_zip,receiver_mobile,receiver_phone,orders");

		Date now = DateUtil.getCurrentTime();

		if (start == null) {
			req.setStartModified(DateUtils.addMinutes(now, -72));
		} else {
			req.setStartModified(start);
		}
		if (end == null) {
			req.setEndModified(DateUtils.addMinutes(now, -60));
		} else {
			req.setEndModified(end);
		}
		if ((page != null) && (pageSize != null)) {
			req.setPageNo(page.longValue());
			req.setPageSize(pageSize.longValue());
		}
		//
		// int dateNum = Integer.valueOf(DateUtil.convertDateToString("HHmm", now));
		//
		// if (start == null) {
		// if (dateNum < 5) {
		// Calendar c = DateUtil.getTargetDateAddDays(-1, DateUtil.getFirstTimestamp(Calendar.DAY_OF_MONTH, now));
		// req.setStartModified(c.getTime());
		// } else {
		// // req.setStartModified(DateUtils.addMinutes(DateUtil.getFirstTimestamp(Calendar.DAY_OF_MONTH, now), -75));
		// //默认为抓12分钟前
		// req.setStartModified(DateUtils.addMinutes(DateUtil.getFirstTimestamp(Calendar.DAY_OF_MONTH, now), -12));
		// }
		//
		// } else {
		// req.setStartModified(start);
		// }
		// if (end == null) {
		// if (dateNum < 5) {
		// Calendar c = DateUtil.getTargetDateAddDays(-1, DateUtil.getLastTimestamp(Calendar.DAY_OF_MONTH, now));
		// req.setStartModified(c.getTime());
		// } else {
		// req.setEndModified(DateUtils.addMinutes(now, -60));
		// }
		// } else {
		// req.setEndModified(end);
		// }

		if (StringUtils.isBlank(status)) {
			req.setStatus("WAIT_SELLER_SEND_GOODS");
		} else {
			req.setStatus(status);
		}
		// req.setUseHasNext(Boolean.TRUE);

		List<Orders> result = new ArrayList<Orders>();
		TradesSoldIncrementGetResponse res = (TradesSoldIncrementGetResponse) executeHttp(req);

		if ((res != null) && res.isSuccess() && (res.getTrades() != null)) {
			for (Trade trade : res.getTrades()) {
				try {
					boolean isExist = checkOrderExist(String.valueOf(trade.getTid()));
					boolean isSkip = false;
					if (skipList != null) {

						for (String skipTid : skipList) {
							if (skipTid.equals(String.valueOf(trade.getTid()))) {
								isSkip = true;
								break;
							}
						}
					}
					if (!isExist && !isSkip) {
						Orders order = getTradeAndSaveToOrder(String.valueOf(trade.getTid()), trade.getTradeFrom());
						if (null != order) {
							result.add(order);
						}
					} else {
						logger.warn("tid:" + trade.getTid() + " was downloaded or skiped!");
					}

				} catch (Exception e) {
					smsService.sendSms("18621771250", "淘宝订单下载失败:" + trade.getTid(), "");
					// 不正常单避开
					e.printStackTrace();
					// throw new RuntimeException(e);
				}
			}
		}
		/**
		 * 检查订单数与
		 */
		return res.getTotalResults().intValue();

	}

	/**
	 * @param req
	 * @param object
	 * @return
	 */
	private TaobaoResponse executeHttp(TaobaoRequest req) {
		Option op = JspUtil.menuOption("SystemValue", "tmall_sessionKey");
		String sessionKey = op.getMemo1();
		TaobaoClient client = new DefaultTaobaoClient(apiUrl, apiKey[0], apiSecret[0]);
		TaobaoResponse res = null;
		try {
			if (StringUtils.isBlank(sessionKey)) {
				res = client.execute(req);
			} else {
				res = client.execute(req, sessionKey);
			}
			logger.debug("input:{}, output:{}", res.getParams(), res.getBody());
			if (!res.isSuccess()) {
				logger.error("input:{}, output:{}", res.getParams(), res.getBody());
			}
		} catch (ApiException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		return res;
	}

	public Item getItem(Long num_iid) {
		ItemGetRequest req = new ItemGetRequest();
		req.setFields("num_iid,title,price,outer_iid,quantity,sku");
		req.setNumIid(num_iid);
		ItemGetResponse response = (ItemGetResponse) executeHttp(req);
		return response.getItem();
	}

	// 检查是否应下载订单：预设付款后一小时下载
	private boolean isPaymentDateNeedDownload(Date paymentDate) {
		Calendar checkDate = Calendar.getInstance();
		checkDate.add(Calendar.HOUR_OF_DAY, -1);
		System.out.println("checkDate:" + checkDate);
		System.out.println("paymentDate:" + paymentDate);
		if (checkDate.getTime().after(paymentDate)) {
			// 若检查时间晚于付款时间
			return true;

		}

		return false;
	}

	// private boolean isPaymentDateNeedDownload(Date paymentDate) {
	// return true;
	// }

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.taobao.service.TaobaoService#getTrade(java.lang.String)
	 */
	@Override
	@Transactional(readOnly = false)
	public Orders getTradeAndSaveToOrder(String tid, String tradeFrom) {
		Orders result = null;
		Trade trade = getTrade(tid);
		boolean isNeedDownload = isPaymentDateNeedDownload(trade.getPayTime());
		if (isNeedDownload) {
			if (null != trade) {
				result = tradeToOrder(trade, false, tradeFrom);
			}
		} else {
			logger.debug("not need to download tid:" + tid);
		}
		return result;
	}

	public Trade getTrade(String tid) {
		TradeFullinfoGetRequest req = new TradeFullinfoGetRequest();
		req.setTid(Long.valueOf(tid));
		req
				.setFields("alipay_id,buyer_nick,buyer_email,buyer_alipay_no,buyer_message,buyer_memo,promotion,promotion_details,seller_nick,buyer_nick,title,type,created,tid,seller_rate,buyer_rate,status,payment,discount_fee,adjust_fee,post_fee,total_fee,pay_time,end_time,modified,consign_time,buyer_obtain_point_fee,point_fee,real_point_fee,received_payment,commission_fee,pic_path,num_iid,num,price,cod_fee,cod_status,shipping_type,receiver_name,receiver_state,receiver_city,receiver_district,receiver_address,receiver_zip,receiver_mobile,receiver_phone,orders");

		TradeFullinfoGetResponse res = (TradeFullinfoGetResponse) executeHttp(req);
		Trade trade = res.getTrade();
		return trade;
	}

	@Transactional(readOnly = false)
	public Orders getTradeForcePresent(String tid) {
		Orders result = null;
		Trade trade = getTrade(tid);
		boolean isNeedDownload = isPaymentDateNeedDownload(trade.getPayTime());
		if (isNeedDownload) {
			if (null != trade) {
				result = tradeToOrder(trade, true, "WAP");
			}
		} else {
			logger.debug("not need to download tid:" + tid);
		}
		return result;
	}

	@Transactional(readOnly = false)
	public void csvImportOrder(String listFile, String detailFileStr) throws Exception {
		File file = new File(listFile);
		File detailFile = new File(detailFileStr);
		int BUFSIZE = 2048;
		byte[] bbuf = new byte[BUFSIZE];
		// byte[] BOM_UTF8 = { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF };

		InputStream in = new FileInputStream(file);

		// FileOutputStream op = new FileOutputStream(file);
		int length = 0;
		BufferedReader br = new BufferedReader(new InputStreamReader(in));
		String theLine = null;
		int rowAt = 0;
		while ((in != null) && ((theLine = br.readLine()) != null)) {
			// 第一行是标题
			if (rowAt == 0) {
				continue;
			}
			rowAt++;
			// op.write(bbuf, 0, length);
			String record = theLine;
			String[] recordArray = record.split(",");
			Map<String, Object> theRecord = new HashMap<String, Object>();
			int outerOrderIdAt = 0;
			int amountAt = 3;
			int shipFareAt = 4;
			int pointAmountAt = 5;
			int mustPayAt = 6;
			int cashAt = 6;
			int joinMustPayAt = 6;
			int memoAt = 11;
			int receiverNameAt = 12;
			int fullAddrAt = 13;
			int phoneAt = 15;
			int mobileAt = 16;
			int createDateAt = 17;
			int paymentDateAt = 18;
			int invoiceTitleAt = 30;

			String outerOrderId = recordArray[0];
			theRecord.put("outerOrderId", recordArray[0]);
			theRecord.put("amount", BigDecimal.valueOf(Float.valueOf(recordArray[amountAt].replaceAll("\"", ""))).setScale(2,
					BigDecimal.ROUND_DOWN));
			theRecord.put("shipFare", BigDecimal.valueOf(Float.valueOf(recordArray[shipFareAt].replaceAll("\"", "")))
					.setScale(2, BigDecimal.ROUND_DOWN));
			BigDecimal pointAmount = BigDecimal.valueOf(Integer.valueOf(recordArray[pointAmountAt].replaceAll("\"", "")));
			theRecord.put("pointAmount", pointAmount.divide(BigDecimal.valueOf(100)).setScale(2, BigDecimal.ROUND_DOWN));
			theRecord.put("mustPay", BigDecimal.valueOf(Float.valueOf(recordArray[mustPayAt].replaceAll("\"", ""))).setScale(
					2, BigDecimal.ROUND_DOWN));
			theRecord.put("cash", BigDecimal.valueOf(Float.valueOf(recordArray[cashAt].replaceAll("\"", ""))).setScale(2,
					BigDecimal.ROUND_DOWN));
			theRecord.put("joinMustPay", BigDecimal.valueOf(Float.valueOf(recordArray[joinMustPayAt].replaceAll("\"", "")))
					.setScale(2, BigDecimal.ROUND_DOWN));
			theRecord.put("memo", recordArray[memoAt].replaceAll("\"", ""));
			theRecord.put("receiverName", recordArray[receiverNameAt].replaceAll("\"", ""));
			String fullAddr = recordArray[fullAddrAt].replaceAll("\"", "");
			String addrArr[] = fullAddr.split(" ");
			theRecord.put("receiverProvince", addrArr[0]);
			theRecord.put("receiverCity", addrArr[1]);
			theRecord.put("receiverArea", addrArr[2]);
			String receiverAddr = " ";
			if (addrArr.length > 3) {
				receiverAddr += addrArr[3];
			}
			if (addrArr.length > 4) {
				receiverAddr += addrArr[4];
			}
			if (addrArr.length > 5) {
				receiverAddr += addrArr[5];
			}
			if (addrArr.length > 6) {
				receiverAddr += addrArr[6];
			}
			if (addrArr.length > 7) {
				receiverAddr += addrArr[7];
			}
			if (addrArr.length > 8) {
				receiverAddr += addrArr[8];
			}
			theRecord.put("receiverAddr", receiverAddr);
			int rowS = fullAddr.length() - 7;
			int rowE = fullAddr.length() - 1;
			theRecord.put("receiverZip", fullAddr.substring(rowS, rowE));
			String phone = recordArray[phoneAt].replaceAll("\"", "");
			theRecord.put("receiverPhone", phone);
			// if (phone != null && phone.length() > 0) {
			// String phoneArr[] = phone.split("-");
			// if (phoneArr.length > 1) {
			// theRecord.put("receiverPhoneArea", phoneArr[0]);
			// theRecord.put("receiverPhone", phoneArr[1]);
			//
			// } else {
			// theRecord.put("receiverPhone", phoneArr[0]);
			//
			// }
			// }
			theRecord.put("receiverMobile", recordArray[mobileAt].replaceAll("\"", ""));
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			theRecord.put("orderDate", sdf.parse(recordArray[createDateAt].replaceAll("\"", "")));
			theRecord.put("paymentDate", sdf.parse(recordArray[paymentDateAt].replaceAll("\"", "")));
			theRecord.put("invoiceTitle", recordArray[invoiceTitleAt].replaceAll("\"", ""));

			// detail
			List<Map<String, Object>> theDetailRecords = new ArrayList<Map<String, Object>>();

			InputStream in_detail = new FileInputStream(detailFile);
			BufferedReader brDetail = new BufferedReader(new InputStreamReader(in_detail));
			String theDetailLine = null;
			int detailRowAt = 0;
			while ((in_detail != null) && ((theDetailLine = brDetail.readLine()) != null)) {
				if (detailRowAt == 0) {
					continue;
				}
				detailRowAt++;
				String detailRecord = theDetailLine;
				String[] detailRecordArr = detailRecord.split(",");
				String detailOuterOrderId = detailRecordArr[0];
				if (detailOuterOrderId.equals(outerOrderId)) {
					int productNameAt = 1;
					int unitPriceAt = 2;
					int qtyAt = 3;
					int specIdAt = 4;
					int prodSpecNameAt = 5;
					Map<String, Object> detailRecordMap = new HashMap<String, Object>();
					detailRecordMap.put("productName", detailRecordArr[productNameAt].replaceAll("\"", ""));
					detailRecordMap.put("unitPrice", BigDecimal.valueOf(Float.valueOf(detailRecordArr[unitPriceAt].replaceAll(
							"\"", ""))));
					detailRecordMap.put("qty", BigDecimal.valueOf(Integer.valueOf(detailRecordArr[qtyAt].replaceAll("\"", ""))));
					detailRecordMap.put("specId", detailRecordArr[specIdAt].replaceAll("\"", ""));
					detailRecordMap.put("prodSpecName", detailRecordArr[prodSpecNameAt].replaceAll("\"", ""));
					theDetailRecords.add(detailRecordMap);

				}
			}
			in_detail.close();
			brDetail.close();
			// 写入资料库
			recordToOrder(theRecord, theDetailRecords);

		}
		in.close();
		br.close();
	}

	public String[] getApiKey() {
		return apiKey;
	}

	public String[] getApiSecret() {
		return apiSecret;
	}

	public void setApiKey(String[] apiKey) {
		this.apiKey = apiKey;
	}

	public void setApiSecret(String[] apiSecret) {
		this.apiSecret = apiSecret;
	}

	@Transactional(readOnly = false)
	public void syncTaobaoOrders() {
		Object[] results = baseMgr.queryByHql("from Orders where outerOrderId is not null and orderSt=? and domainSrc=?",
				new Object[] { Orders.ORDER_ST.INIT.getValue(), "yaodian100.tmall.com" });
		if ((results != null) && (results.length > 0)) {
			for (Object obj : results) {
				Orders order = (Orders) obj;
				if (order.getMustPay().floatValue() > 0) {
					if (order.getMemo().length() > ("msg:null,memo:null").length()) {
						// 假定客戶有要求
						// 不自動更新狀態，待人工檢查後更新
					} else {
						// 客人無特殊要求
						order.setOrderSt("20");
						orderService.update(order);
					}
				} else {
					logger.error("something wrong with this order:" + order.getOrderId());
				}
			}
		} else {
			logger.debug("nothing to sync!");
		}
	}

	public List<PropValue> getSkuProps(String cid, String props) {
		ItempropvaluesGetRequest req = new ItempropvaluesGetRequest();
		req.setFields("cid,pid,prop_name,vid,name,name_alias,status,sort_order");
		req.setCid(Long.valueOf(cid));
		req.setPvs(props);
		ItempropvaluesGetResponse response = (ItempropvaluesGetResponse) executeHttp(req);
		return response.getPropValues();
	}

	@Transactional(readOnly = false)
	public Orders updateProductDetailNonInventory(String orderId, Long orderProdId, Long specId, BigDecimal unitPrice,
			String prodName, String specName, String outerCid, String outerProdId, String outerSkuId) throws CoreException {
		Orders order = orderService.get(orderId);
		if (order.isSync()) {
			return order;
		}
		OrderProduct op = null;
		for (OrderProduct theOp : order.getOrderProduct()) {
			if (theOp.getOrderProdId().equals(orderProdId)) {
				op = theOp;
			}
		}

		Specification spec = productService.getSpecification(specId);
		Product prod = null;
		// TODO
		if (spec == null) {
			spec = new Specification();
			spec.setSpecificationId(specId);
			spec.setSpecificationName(specName);
			prod = new Product();
			prod.setProductId("00000001");
			prod.setProductName(prodName);
		} else {
			prod = productService.get(spec.getProductId());
		}

		Shelf shelf = new Shelf();
		shelf.setShelfPrice(unitPrice);
		OrderProductDetail opd = new OrderProductDetail(prod, spec, shelf);
		opd.setQty(1);
		if (StringUtils.isNotBlank(prodName)) {
			opd.setProdName(prodName);
		}
		if (StringUtils.isNotBlank(specName)) {
			opd.setProdSpecName(specName);
		}
		opd.setOuterCid(outerCid);
		opd.setOuterProdId(outerProdId);
		opd.setOuterSkuId(outerSkuId);
		op.addDetail(opd);

		orderService.save(order);
		return order;
	}

	@Transactional(readOnly = false)
	public Orders updateTmallOrder(String orderId, String[] presentQty, String[] specProp) {
		Orders order = (Orders) baseMgr.get(Orders.class, orderId);

		// Map<Long, Integer> qtys = new HashMap<Long, Integer>();
		Map<Long, Stack<BigDecimal>> discounts = new HashMap<Long, Stack<BigDecimal>>();
		for (OrderProduct op : order.getOrderProduct()) {
			for (OrderProductDetail opd : op.getOrderProductDetail()) {
				if ((opd.getOuterCid() != null) && (opd.getOuterCid().length() > 0)) {
					// qtys.put(opd.getOrderDetailId(), opd.getQty());
					// 折份折扣
					Stack<BigDecimal> discountStack = new Stack<BigDecimal>();
					BigDecimal currentDiscountSum = BigDecimal.ZERO;
					for (int i = 1; i <= opd.getQty(); i++) {
						BigDecimal currentDiscount = op.getDiscount().divide(BigDecimal.valueOf(opd.getQty())).setScale(2,
								BigDecimal.ROUND_HALF_DOWN);

						if (i != opd.getQty()) {
							currentDiscountSum = currentDiscountSum.add(currentDiscount);
							discountStack.push(currentDiscount);
						}
						if (i == opd.getQty()) {
							// 最后一笔用减的
							discountStack.push(op.getDiscount().subtract(currentDiscountSum));
						}
					}
					discounts.put(opd.getOrderDetailId(), discountStack);
				}
			}
		}

		if ((presentQty != null) && (presentQty.length > 0)) {
			for (String pq : presentQty) {
				String[] pqSplit = pq.split("@");
				String presentSpecId = pqSplit[0];
				String pqty = pqSplit[1];
				if (Integer.valueOf(pqty).intValue() > 0) {
					Specification spec = (Specification) baseMgr.get(Specification.class, Long.valueOf(presentSpecId));
					Product prod = (Product) baseMgr.get(Product.class, spec.getProductId());
					orderService.updateProduct(orderId, Long.valueOf(presentSpecId), Integer.valueOf(pqty).intValue(), BigDecimal
							.valueOf(0), false, prod.getProductName(), spec.getSpecificationName(), BigDecimal.valueOf(0));
				}
			}
		}
		if (!order.getOrderSt().equals("05")) {
			throw new RuntimeException("This order can't be modify!");
		}

		if ((specProp != null) && (specProp.length > 0)) {
			Map<Long, String> prodNames = new HashMap<Long, String>();
			Map<Long, String> outerCids = new HashMap<Long, String>();
			Map<Long, String> outerProdIds = new HashMap<Long, String>();
			String preOrderProdId = null;
			for (String specP : specProp) {
				String[] props = specP.split("@");
				String isNeedUpdate = props[0];
				String orderProdId = props[1];
				String orderDetailId = props[2];
				String unitPrice = props[3];
				String prodSpecId = props[4];
				String outerSkuId = props[5];
				String prodSpecName = props[6];

				if ("1".equals(isNeedUpdate)) {
					// 修改内容
					OrderProduct op = null;
					if (!orderProdId.equals(preOrderProdId)) {
						preOrderProdId = orderProdId;
						Object[] orderProductDetails = baseMgr.queryByHql("from OrderProductDetail where orderProdId=?",
								new Object[] { Long.valueOf(orderProdId) });

						for (Object obj : orderProductDetails) {
							OrderProductDetail opd = (OrderProductDetail) obj;
							op = opd.getOrderProd();
							prodNames.put(opd.getOrderDetailId(), opd.getProdName());
							outerCids.put(opd.getOrderDetailId(), opd.getOuterCid());
							outerProdIds.put(opd.getOrderDetailId(), opd.getOuterProdId());
						}

					}
					// deleteProductDetail(orderProdId);
					// // 更新orderDetail
					// updateProductDetailNonInventory(orderId, Long.valueOf(orderProdId), Long.valueOf(prodSpecId), BigDecimal
					// .valueOf(Float.valueOf(unitPrice)), prodNames.get(Long.valueOf(orderDetailId)), prodSpecName, outerCids
					// .get(Long.valueOf(orderDetailId)), outerProdIds.get(Long.valueOf(orderDetailId)), outerSkuId);
					Stack<BigDecimal> discountStack = discounts.get(Long.valueOf(orderDetailId));
					orderService.addOuterProduct(orderId, Long.valueOf(prodSpecId), 1, BigDecimal.valueOf(Float
							.valueOf(unitPrice)), false, prodNames.get(Long.valueOf(orderDetailId)), prodSpecName, discountStack
							.pop(), outerCids.get(Long.valueOf(orderDetailId)), outerProdIds.get(Long.valueOf(orderDetailId)),
							outerSkuId);

					// // 删除要修改内容
					if (op != null) {
						// baseMgr.delete(op);
						baseMgr.executeHql("delete from OrderProductDetail where orderProdId=?",
								new Object[] { op.getOrderProdId() });
						baseMgr.executeHql("delete from OrderProduct where orderProdId=?", new Object[] { op.getOrderProdId() });

					}
				}

			}

		}

		return order;
	}
}
